package com.whx.search.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.constant.RedisConstant;
import com.hmall.common.dto.PageDTO;
import com.hmall.common.pojo.Item;
import com.whx.search.mapper.SearchMapper;
import com.whx.search.pojo.dto.SearchDto;
import com.whx.search.pojo.vo.SearchVo;
import com.whx.search.service.SearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @Author whx
 * @Date 2024/11/14 17:13
 */
@Service
public class SearchServiceImpl extends ServiceImpl<SearchMapper, Item> implements SearchService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SearchMapper searchMapper;

    @Autowired
    private RestHighLevelClient client;

    @Override
    public SearchVo doFilter(SearchDto searchDto) {

        List<Item> itemList = searchMapper.selectList(null);

        List<String> brandList = itemList.stream().map(Item::getBrand).distinct().collect(Collectors.toList());
        List<String> categoryList = itemList.stream().map(Item::getCategory).distinct().collect(Collectors.toList());

        return new SearchVo(categoryList, brandList);
    }

    @Override
    public PageDTO<Item> pageDto(SearchDto searchDto) {

        List<Item> itemList = null;

        if (
                searchDto.getKey().equals("") &&
                        searchDto.getPage() == 1 &&
                        searchDto.getSize() == 20 &&
                        searchDto.getSortBy().equals("default") &&
                        searchDto.getCategory() == null &&
                        searchDto.getBrand() == null &&
                        searchDto.getMinPrice() == null &&
                        searchDto.getMaxPrice() == null
        ) {

            String strList = redisTemplate.opsForValue().get(RedisConstant.PREHEAT_LIST);
            itemList = JSONUtil.toList(strList, Item.class); // 前20条数据
        }

        if (itemList == null || itemList.size() == 0) {
            SearchRequest request = new SearchRequest("item");

            BoolQueryBuilder boolQuery = new BoolQueryBuilder();

            // 判断是否穿传key
            String key = searchDto.getKey();
            if (key != null && !"".equals(key)) {
                // 传了key
                boolQuery.must(QueryBuilders.matchQuery("name", key));
            } else {
                // 没传
                boolQuery.must(QueryBuilders.matchAllQuery());
            }

            // 条件查询-判断品牌
            if (searchDto.getBrand() != null) {
                boolQuery.filter(QueryBuilders.termQuery("brand", searchDto.getBrand()));
            }

            // 条件查询-判断分类
            if (searchDto.getCategory() != null) {
                boolQuery.filter(QueryBuilders.termQuery("category", searchDto.getCategory()));
            }

            // 条件查询-价格
            if (searchDto.getMaxPrice() != null) {
                boolQuery.filter(QueryBuilders
                        .rangeQuery("price")
                        .lte(searchDto.getMaxPrice())
                        .gte(searchDto.getMinPrice())
                );
            }

            request.source().query(boolQuery);

            // 结果查询-分页
            int from = (searchDto.getPage() - 1) * searchDto.getSize();
            request.source().from(from).size(searchDto.getSize());


            try {
                ArrayList<Item> list = new ArrayList<>();

                SearchResponse search = client.search(request, RequestOptions.DEFAULT);

                // 第一层hits
                SearchHits hits = search.getHits();

                long total = hits.getTotalHits().value;

                // 第二层hits
                SearchHit[] hits1 = hits.getHits();

                for (SearchHit hit : hits1) {
                    String JSONStr = hit.getSourceAsString();

                    Item item = JSONUtil.toBean(JSONStr, Item.class);

                    list.add(item);
                }

                return PageDTO.of(total, list);

            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }

        PageDTO<Item> itemPageDTO = new PageDTO<>();

        String total = redisTemplate.opsForValue().get(RedisConstant.PREHEAT_TOTAL);

        itemPageDTO.setTotal(Long.valueOf(total));
        itemPageDTO.setList(itemList);

        return itemPageDTO;

//        SearchRequest request = new SearchRequest("item");
//
//        BoolQueryBuilder boolQuery = new BoolQueryBuilder();
//
//        // 判断是否穿传key
//        String key = searchDto.getKey();
//        if(key!=null && !"".equals(key)){
//            // 传了key
//            boolQuery.must(QueryBuilders.matchQuery("name", key));
//        }else {
//            // 没传
//            boolQuery.must(QueryBuilders.matchAllQuery());
//        }
//
//        // 条件查询-判断品牌
//        if(searchDto.getBrand()!=null){
//            boolQuery.filter(QueryBuilders.termQuery("brand", searchDto.getBrand()));
//        }
//
//        // 条件查询-判断分类
//        if(searchDto.getCategory()!=null){
//            boolQuery.filter(QueryBuilders.termQuery("category", searchDto.getCategory()));
//        }
//
//        // 条件查询-价格
//        if(searchDto.getMaxPrice()!=null){
//            boolQuery.filter(QueryBuilders
//                    .rangeQuery("price")
//                    .lte(searchDto.getMaxPrice())
//                    .gte(searchDto.getMinPrice())
//            );
//        }
//
//        request.source().query(boolQuery);
//
//        // 结果查询-分页
//        int from = ( searchDto.getPage() - 1 ) * searchDto.getSize();
//        request.source().from(from).size(searchDto.getSize());
//
//
//        try {
//            ArrayList<Item> list = new ArrayList<>();
//
//            SearchResponse search = client.search(request, RequestOptions.DEFAULT);
//
//            // 第一层hits
//            SearchHits hits = search.getHits();
//
//            long total = hits.getTotalHits().value;
//
//            // 第二层hits
//            SearchHit[] hits1 = hits.getHits();
//
//            for (SearchHit hit : hits1) {
//                String JSONStr = hit.getSourceAsString();
//
//                Item item = JSONUtil.toBean(JSONStr, Item.class);
//
//                list.add(item);
//            }
//
//            return PageDTO.of(total, list);
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return null;


//        System.out.println(ThreadLocalUtil.getCurrentId());
//
//        List<Item> itemList = null;
//
//        if(
//                searchDto.getKey().equals("") &&
//                searchDto.getPage() == 1 &&
//                searchDto.getSize() == 20 &&
//                searchDto.getSortBy().equals("default") &&
//                searchDto.getCategory() == null &&
//                searchDto.getBrand() == null &&
//                searchDto.getMinPrice() == null &&
//                searchDto.getMaxPrice() == null
//        ){
//
//            String strList = redisTemplate.opsForValue().get(RedisConstant.PREHEAT_LIST);
//
//             itemList = JSONUtil.toList(strList, Item.class); // 前20条数据
//        }
//
//        if(itemList == null || itemList.size()==0){
//            Page<Item> itemPage = new Page<>(searchDto.getPage(), searchDto.getSize());
//
//            // 创建查询条件
//            LambdaQueryWrapper<Item> queryWrapper = new LambdaQueryWrapper<>();
//
//            queryWrapper.like(searchDto.getKey() != null, Item::getName, searchDto.getKey());
//            queryWrapper.eq(searchDto.getBrand() != null, Item::getBrand, searchDto.getBrand());
//            queryWrapper.eq(searchDto.getCategory() != null, Item::getCategory, searchDto.getCategory());
//            queryWrapper.orderByDesc("price".equals(searchDto.getSortBy()), Item::getPrice);
//            queryWrapper.orderByDesc("sold".equals(searchDto.getSortBy()), Item::getSold);
//            queryWrapper.between(searchDto.getMinPrice() != null && searchDto.getMaxPrice() != null, Item::getPrice, searchDto.getMinPrice(), searchDto.getMaxPrice());
//
//            Page<Item> itemPage1 = searchMapper.selectPage(itemPage, queryWrapper);
//            PageDTO<Item> itemPageDTO = new PageDTO<>();
//            itemPageDTO.setTotal(itemPage1.getTotal());
//            itemPageDTO.setList(itemPage1.getRecords());
//
//            return itemPageDTO;
//        }
//
//        PageDTO<Item> itemPageDTO = new PageDTO<>();
//        String total = redisTemplate.opsForValue().get(RedisConstant.PREHEAT_TOTAL);
//        itemPageDTO.setTotal(Long.valueOf(total));
//        itemPageDTO.setList(itemList);
//        return itemPageDTO;
    }
}
